﻿using System;
using System.Collections.Generic;
using System.Collections.Specialized;
using System.Text;
using System.Web;
using System.Web.Security;
using Castle.MonoRail.Framework;
using Castle.MonoRail.Framework.Helpers;
using Castle.MonoRail.ViewComponents;

namespace StateTheater.Component
{
    public class MenuComponent : ViewComponentEx
    {
        HtmlHelper helper;
        string isHoriz;
        List<string> toHide = new List<string>();

        [ViewComponentParam("SiteMapFile", Default = "~/web.sitemap")]
        public string siteMapFile { get; set; }

        [ViewComponentParam]
        public SiteMapProvider SiteMapProvider { get; set; }

        [ViewComponentParam]
        public string SiteMapProviderID { get; set; }

        [ViewComponentParam(Default = "Menu$1")]
        public string Id { get; set; }

        [ViewComponentParam]
        public string direction { get; set; }

        [ViewComponentParam(Default="Menu")]
        public string cssClass { get; set; }


        public override void Initialize()
        {
			HttpContext.Current.Trace.IsEnabled = true;

            base.Initialize();
//            isHoriz = ((direction == null) ? false : (direction.ToLower()[0] == 'h')).ToString().ToLower();
            helper = new HtmlHelper();

            if (SiteMapProvider == null)
            {
                if (!string.IsNullOrEmpty(SiteMapProviderID))
                {
                    SiteMapProvider = SiteMap.Providers[SiteMapProviderID];
                }
                else if (SiteMap.Provider != null)
                {
                    SiteMapProvider = SiteMap.Provider;
                }

                if (SiteMapProvider == null)
                {
                    // Create an instance of the XmlSiteMapProvider class.
                    XmlSiteMapProvider testXmlProvider = new XmlSiteMapProvider();
                    NameValueCollection providerAttributes = new NameValueCollection(1);
                    providerAttributes.Add("siteMapFile", this.siteMapFile);

                    // Initialize the provider with a provider name and file name.
                    testXmlProvider.Initialize("MenuComponentProvider", providerAttributes);

                    // Call the BuildSiteMap to load the site map information into memory.
                    testXmlProvider.BuildSiteMap();
                    SiteMapProvider = testXmlProvider;
                }
            }
        }
        
        public override void Render()
        {
            base.Render();
            JavascriptHelper helper = new JavascriptHelper(Context, EngineContext, "MenuComponent");
            RenderMenuLevel(SiteMapProvider.RootNode, 0, Id);
            helper.IncludeStandardScripts("Ajax");

			helper.IncludeScriptText("IE", @"function PrepareMenu(id) {$(id).style.textIndent=""-14px""; $(id).style.position=""absolute""; Element.hide(id);}");
			helper.IncludeScriptText("other", @"function PrepareMenu(id) { $(id).style.position=""absolute""; Element.hide(id);}");

			StringBuilder script = new StringBuilder(1000);
            foreach (string menuid in toHide)
            {
				script.AppendFormat("PrepareMenu('{0}');", menuid);
            }
			helper.IncludeScriptText("inline", script.ToString());
			CancelView();
        }

        public void RenderText(string format, params object[] args)
        {
            string content = String.Format(format, args);
            base.RenderText(content);
        }


        private void RenderMenuLevel(SiteMapNode root, int level, string id)
        {
            string collapsed = "Frame";
            if (level > 0)
            {
                collapsed = "Item Collapsed";
            }
			Logger.Info(@"<ul id=""{0}"" class=""{1}{2}"">", id, cssClass, collapsed);
            RenderText(@"<ul id=""{0}"" class=""{1}{2}"">", id, cssClass, collapsed);
            foreach (SiteMapNode item in root.ChildNodes)
            {
                bool allowed = true;
                if (item.Roles != null && item.Roles.Count > 0 && item.Roles[0].ToString() != "*")
                {
                    allowed = false;
                    foreach (string role in item.Roles)
                    {
					if (EngineContext.CurrentUser.IsInRole(role) || Roles.IsUserInRole(role))
                        {
                            allowed = true;
                            break;
                        }
                    }
                }
                if (!allowed)
                    continue;

                string title = item.Title;
                if (string.IsNullOrEmpty(title))
                {
                    if (string.IsNullOrEmpty(item.Url))
                    {
                        RenderText("<hr/>");
                    }
                    else
                    {
                        throw new ArgumentException("title element is required");
                    }
                }
                else
                {
                    if (item.HasChildNodes)
                    {
                        string menuID = MakeUniqueId("Menu:");
//                        RenderText(string.Format("<li onclick=\"Element.toggle('{2}')\" ><a class=\"{0}Item\"href=\"#\">{1}</a>\r\n", cssClass, title, menuID));
						RenderText(string.Format("<li onclick=\"Element.toggle('{2}')\" ><a class=\"{0}Item\">{1}</a>\r\n", cssClass, title, menuID));
						RenderMenuLevel(item, level + 1, menuID);
                        toHide.Add(menuID);
                    }
                    else
                    {
                        RenderText("<li>");

                        string description = item.Description ?? string.Empty;
                        string url = item.Url;
                        if (url[0] == '~')
                            url = VirtualPathUtility.ToAbsolute(url);

                        //                    RenderText(string.Format("<a class=\"{3}\" href=\"{0}\" title=\"{1}\">{2}</a>", url, description, title, cssClass));
                        RenderText(string.Format("<a class=\"{3}Item\" href=\"{0}\" title=\"{1}\">{2}</a>", url, description, title, cssClass));
                    }
                    RenderText("</li>\r\n");
                }
            }
            RenderText("</ul>");
        }
    }

#if false
    [Resource("Menu", "StateTheater.Component.Menu")]
    public class MenuFiles : Controller
    {
        public void Collapsed()
        {
            WriteImage("collapsed_png");
        }

        public void Expanded()
        {
            WriteImage("expanded_png");
        }

        private void WriteImage(string name)
        {
            this.Response.ContentType = "image/png";
            byte[] contents = (byte[])StateTheater.Component.Menu.ResourceManager.GetObject(name);

            this.Response.BinaryWrite(contents);
            CancelView();
        }

        void DefaultAction()
        {
        }
    }
#endif
}
